﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ESBasic;
using ESBasic.ObjectManagement.Forms;
using ESPlus.Application.CustomizeInfo.Passive;
using ESPlus.Application.P2PSession.Passive;
using ESFramework.Demos.Core;
using ESPlus.FileTransceiver;
using ESPlus.Application.FileTransfering.Passive;
using Chat.VideoViewer;
using OMCS.Passive;
using ESPlus.Rapid;

namespace Chat.Forms
{
    public partial class ChatForm : Form, IManagedForm<string>
    {
        private object lockObject = new object();
        private RapidPassiveEngine rapidEngine;

        private string friendID;
        private string currentUserID;
        private IFileOutter fileOutter;
        private ICustomizeOutter customizeInfoOutter;
        private IMultimediaManager multimediaManager = null;
        
        private bool haveCloseVedio = false;
        private bool haveVideo = false;
        public bool HaveVideo
        {
            get{return haveVideo;}
        }

        private IViewer currentViewer = null;
        public ViewerType CurrentViewerType
        {
            get
            {
                if (this.currentViewer != null)
                {
                    return this.currentViewer.Type;
                }
                return ViewerType.None;
            }
        }

        public ChatForm(string _friendID,RapidPassiveEngine _rapidEngine, IMultimediaManager _multimediaManager)
        {
            InitializeComponent();
            this.rapidEngine = _rapidEngine;
            this.friendID = _friendID;
            this.currentUserID = _rapidEngine.CurrentUserID;

           // this.fileOutter = _fileOutter;
            this.fileOutter = _rapidEngine.FileOutter;
            this.textChatControl1.Initialize(_friendID, _rapidEngine);

            this.fileTransferingViewer1.Initialize(this.friendID, this.fileOutter);
            //this.customizeInfoOutter = _customizeInfoOutter;
            this.customizeInfoOutter = _rapidEngine.CustomizeOutter;
            this.textChatControl1.Initialize( _friendID, _rapidEngine);
            this.panel_plus.Visible = false;
            this.Width = 500;

            this.multimediaManager = _multimediaManager;
            this.rapidEngine.P2PController.P2PConnectAsyn(this.friendID);
        }

        #region IManagedForm<string> 成员

        public string FormID
        {
            get { return this.friendID; }
        }

        #endregion

        public void SelfOrFriendOffline()
        {
            this.textChatControl1.Enabled = false;
            this.Text += "     已经掉线";
        }

        public void ShowOtherTextChat(string userID, TextChatContract contract)
        {
            this.textChatControl1.ShowOtherTextChat(userID, contract);
        }

        //当接收到对方的文件传送请求时
        public void OnFileRequest(string fileID, string senderID, string fileName)
        {
            if (DialogResult.OK == MessageBox.Show(string.Format("{0}要求向你传送文件{1}，你是否同意接收？", senderID, fileName), "文件传输", MessageBoxButtons.OKCancel))
            {
                string savePath = ESBasic.Helpers.FileHelper.GetPathToSave("保存", fileName, null);
                if (!string.IsNullOrEmpty(savePath))
                {
                    this.fileOutter.BeginReceiveFile(fileID, savePath);
                }
                else
                {
                    this.RejectFile(fileID, fileName);
                }
            }
            else
            {
                this.RejectFile(fileID, fileName);
            }
        }

        private void RejectFile(string fileID, string fileName)
        {
            TransferingProject fileInfo = this.fileOutter.GetTransferingProject(fileID);
            if (fileInfo != null)
            {
                this.textChatControl1.ShowRejectFile(fileName);
                this.fileOutter.RejectFile(fileID);
            }
        }

        //对方同意或者拒绝接收文件
        public void OnFileResponse(TransferingProject transferingProject, bool agreeRecive)
        {
            this.textChatControl1.ShowSystemMessage(transferingProject, agreeRecive);
        }

        //文件传送开始时，设置进度面板可见性
        private void fileTransferingViewer1_FileTransStarted(string obj1, bool obj2)
        {
            if (!this.panel_plus.Visible)
            {
                this.panel_plus.Visible = true;
                this.Width = 700;
            }

        }

        //文件传输中断
        private void fileTransferingViewer1_FileTransDisruptted(string fileName, bool isSender, FileTransDisrupttedType fileTransDisrupttedType)
        {
            this.textChatControl1.ShowFileTransferFailed(fileName, isSender, fileTransDisrupttedType);
            if (!this.fileTransferingViewer1.IsFileTransfering)
            {
                this.panel_plus.Visible = false;
                this.Width = 500;
            }
        }

        //文件续传开始
        private void fileTransferingViewer1_FileResumedTransStarted(string fileName, bool isSender)
        {
            this.textChatControl1.ShowFileResumedTransStarted(fileName);
        }

        //文件传输成功
        private void fileTransferingViewer1_FileTransCompleted(string fileName, bool isSender)
        {
            this.textChatControl1.ShowFileTransCompleted(fileName, isSender);
        }

        internal void ShowSenderCancelMessage(string fileName)
        {
            this.textChatControl1.ShowSenderCancelMessage(fileName);
        }

        //所有文件传送完成
        private void fileTransferingViewer1_AllTaskFinished()
        {
            if (this.panel_plus.Visible)
            {
                this.panel_plus.Visible = false;
                this.Width = 500;
            }
        }

        //显示P2P连接的状态
        public void ShowP2PChannelState(P2PChannelState state)
        {
            this.Text = (state != null) ? string.Format("正在与{0}对话中 【{1}直连:{2}】...", this.friendID, state.ProtocolType, state.DestIPE) : string.Format("正在与{0}对话中...", this.friendID);
        }

        //关闭窗口前，判断当前是否有文件正在传输，如果有，则提示用户是否
        private void ChatForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            List<string> fileIDs = this.fileOutter.GetTransferingAbout(this.friendID);
            if (fileIDs != null && fileIDs.Count > 0)
            {
                DialogResult result = MessageBox.Show("如果关闭窗口，就会中止文件传送。是否关闭窗口？", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.None);
                if (result == DialogResult.OK)
                {
                    this.fileOutter.CancelTransferingAbout(this.friendID);
                }
                else
                {
                    e.Cancel = true;
                }
            }

            e.Cancel = false;
            if (this.haveVideo)
            {
                DialogResult result = MessageBox.Show("关闭窗口", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.None);
                if (result == DialogResult.OK)
                {
                    if (this.CurrentViewerType == ViewerType.VideoRequest)
                    {
                        this.rapidEngine.CustomizeOutter.Send(this.friendID, InformationTypes.VideoResult, BitConverter.GetBytes(false));
                    }
                    else if (this.CurrentViewerType == ViewerType.VideoView)
                    {
                        this.rapidEngine.CustomizeOutter.Send(this.friendID, InformationTypes.CloseVideo, null);
                    }
                    this.CloseVideoFunction(-1, "");
                }
                else
                {
                    e.Cancel = true;
                }
            }
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            try
            {
                //打开聊天窗口
                this.OpenVideoViewer(ViewerType.VideoView, true);
                //发送消息给对方
                this.rapidEngine.CustomizeOutter.Send(this.friendID, InformationTypes.VideoRequest, null);
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }
        }

        public void OpenVideoViewer(ViewerType viewerType, bool showWaitingInfo)
        {
            if(this.InvokeRequired)
            {
                this.Invoke(new CbGeneric<ViewerType, bool>(this.OpenVideoViewer), viewerType, showWaitingInfo);
            }
            else
            {
                this.haveCloseVedio = false;
                TabPage page;
                if(this.tabControl1.TabPages.Count == 0)
                {
                    page = new TabPage("视频");
                    this.tabControl1.TabPages.Add(page);
                }
                else
                {
                    page = this.tabControl1.TabPages[0];
                    (page.Controls[0] as IViewer).Close();
                    page.Controls.Clear();
                    this.Width = this.Width - this.panel_plus.Width;
                }
                switch (viewerType)
                {
                    case ViewerType.VideoRequest:
                        {
                           VideoRequestViewer videoRequestViewer = new VideoRequestViewer();
                            videoRequestViewer.Dock = System.Windows.Forms.DockStyle.Fill;
                            videoRequestViewer.ReceiveVideo +=new CbGeneric(videoRequestViewer_ReceiveVideo);
                            videoRequestViewer.RejectVideo +=new CbGeneric(videoRequestViewer_RejectVideo);
                            page.Controls.Add(videoRequestViewer);
                            this.currentViewer = videoRequestViewer;
                            this.panel_plus.Visible = true;
                            int screenWidth = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
                            this.Width = this.Width + 224 > screenWidth?screenWidth:this.Width+24;
                            this.panel_plus.Width = 224;
                            break;
                        }
                    case ViewerType.VideoView:
                        {
                            VideoViewer.VideoViewer videoViewer = new VideoViewer.VideoViewer(this.currentUserID, this.friendID, showWaitingInfo, this.multimediaManager);
                            videoViewer.CloseVideo +=new CbGeneric(videoViewer_CloseVideo);
                            videoViewer.offlineCloseVideo +=new CbGeneric(videoViewer_OfflineCloseVideo);

                            page.Controls.Add(videoViewer);
                            this.panel_plus.Visible = true;
                            int screenWidth = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
                            this.Width = this.Width +346 > screenWidth? screenWidth:this.Width +346;
                            this.panel_plus.Width = 346;
                            this.currentViewer = videoViewer;
                            break;
                        }
                }
                this.haveVideo = true;
                this.toolStripButton_video.Enabled = false;
            }
        }

        void videoRequestViewer_ReceiveVideo()
        {
            this.rapidEngine.CustomizeOutter.Send(this.friendID, InformationTypes.VideoResult, BitConverter.GetBytes(true), true, ESFramework.ActionTypeOnChannelIsBusy.Continue);
            this.OpenVideoViewer(ViewerType.VideoView, false);
            this.ConnectVideo();
        }

        public void ConnectVideo()
        {
            if (this.currentViewer != null)
            {
                if (this.multimediaManager.Available)
                {
                    (this.currentViewer as VideoViewer.VideoViewer).Connect();
                }
            }
        }

        #region videoRequestViewer_RejectVideo
        //拒绝视频
        void videoRequestViewer_RejectVideo()
        {
            this.rapidEngine.CustomizeOutter.Send(this.friendID, InformationTypes.VideoResult, BitConverter.GetBytes(false));
            this.CloseVideoViewer();
        }
        #endregion

        #region CloseVideoViewer
        public void CloseVideoViewer()
        {
            try
            {
                if (this.InvokeRequired)
                {
                    this.Invoke(new CbGeneric(this.CloseVideoViewer));
                }
                else
                {
                    if (this.currentViewer != null)
                    {
                        this.currentViewer.Close();
                        this.currentViewer = null;
                        this.tabControl1.TabPages.RemoveAt(0);
                    }
                    this.haveVideo = false;
                    this.panel_plus.Visible = false;
                    this.Width = this.Width = this.panel_plus.Width >= 400 ? this.Width - this.panel_plus.Width : 400;
                    this.toolStripButton_video.Enabled = true;
                }
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }
        }
        #endregion

        #region videoViewer_CloseVideo
        void videoViewer_CloseVideo()
        {
            this.CloseVideoFunction(InformationTypes.CloseVideo, "自己挂断视频");
        }
        #endregion

        #region CloseVideoFunction
        public void CloseVideoFunction(int informationType, string showMessage)
        {
            lock (this.lockObject)
            {
                if (this.haveCloseVedio) return;
                this.haveCloseVedio = true;
            }
            try
            {
                if (informationType > 0)
                {
                    this.rapidEngine.CustomizeOutter.Send(this.friendID, informationType, null, true, ESFramework.ActionTypeOnChannelIsBusy.Continue);
                }
                this.CloseVideoViewer();
                this.multimediaManager.DisconnectGuest(this.friendID, OMCS.MultimediaDeviceType.Camera, false);

                if (!string.IsNullOrEmpty(showMessage))
                {
                    this.textChatControl1.ShowSystemMessage(showMessage);
                }
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }
        }
        #endregion

        #region videoViewer_OfflineCloseVideo
        void videoViewer_OfflineCloseVideo()
        {
            this.CloseVideoFunction(InformationTypes.NetReasonCloseVideo, "网络原因，视频中断");
        }
        #endregion

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            string filePath = ESBasic.Helpers.FileHelper.GetFileToOpen("打开");
            if (filePath == null)
            {
                return;
            }
            string fileID;
            SendingFileParas sendingFileParas = new SendingFileParas(20480, 0);
            this.fileOutter.BeginSendFile(this.friendID, filePath, null, sendingFileParas, out fileID);
        }

        private void toolStripButton2_Click_1(object sender, EventArgs e)
        {
            WhiteBoardForm form = new WhiteBoardForm("admin");
            form.Show();
        }

        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            try
            {
                DesktopForm form = new DesktopForm(friendID);
                form.Show();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }
        }
    }
}
